//
// Created on 2024/7/1.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".

#ifndef OHOS_GL_DRAWER_H_
#define OHOS_GL_DRAWER_H_

#include <map>
#include <GLES3/gl3.h>
#include <GLES3/gl32.h>
#include <GLES2/gl2ext.h>
#include <native_window/external_window.h>
#include "ohos_shader_program.h"
#include "ohos_video_buffer.h"

namespace webrtc {

const char *GetGLErrorString();

static std::string DEFAULT_VERTEX_SHADER = R"delimiter(
attribute vec4 position;
attribute vec4 texCoord;

varying vec2 vTexCoord;

uniform mat4 matTransform;

void main()
{
    gl_Position = position;
    vTexCoord = (matTransform * texCoord).xy;
}
)delimiter";

class OhosGLDrawer {
public:
    class ShaderCallbacks {
    public:
        virtual void OnNewShader(std::shared_ptr<ShaderProgram> shader) = 0;
        virtual void OnPrepareShader(std::shared_ptr<ShaderProgram> shader, float matrix[16],
            int frameWidth, int frameHeight, int viewportWidth, int viewportHeight) = 0;
    };
    OhosGLDrawer(std::string fragmentShader = std::string(), std::shared_ptr<ShaderCallbacks> shaderCallbacks = nullptr);
    ~OhosGLDrawer();
    void CreateGLResources();
    void CleanGLResources();
    virtual void DrawFrame(OhosVideoBuffer::TextureBuffer buffer, float *matrix, int frameWidth, int frameHeight,
        int viewportX, int viewportY, int viewportWidth, int viewportHeight);
private:
    bool PrePareShader(OhosBufferType frameType, float *matrix, int frameWidth,
        int frameHeight, int viewportX, int viewportY, int viewportWidth, int viewportHeight);
    void DrawOES(GLuint textureID, float *matrix, int frameWidth, int frameHeight, int viewportX, int viewportY,
        int viewportWidth, int viewportHeight);
    void DrawRgb(int textureId, float *matrix, int frameWidth, int frameHeight,
        int viewportX, int viewportY, int viewportWidth, int viewportHeight);
    void DrawYuv(int *yuvTextures, float *matrix, int frameWidth, int frameHeight,
        int viewportX, int viewportY, int viewportWidth, int viewportHeight);

    OhosBufferType currentFrameType_ {OhosBufferType::OES};
    std::shared_ptr<ShaderProgram> shaderProgram_;
    std::shared_ptr<ShaderCallbacks> shaderCallbacks_;
    std::string fragmentShader_;
    static std::map<OhosBufferType, std::string> shaderMap_;
    GLuint vertexArrayObject_ = 0;
    GLuint vertexBufferObject_ = 0;
};

}// namespace webrtc
#endif //OHOS_GL_DRAWER_H_
